package com.openapi.server;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;

public class SubDelimiterBasedFrameDecoder extends DelimiterBasedFrameDecoder {

    private final ByteBuf priorDelimiter;

    public SubDelimiterBasedFrameDecoder(int maxFrameLength,ByteBuf delimiter, ByteBuf... delimiters) {
        super(maxFrameLength, delimiters);

        if (delimiters == null) {
            throw new NullPointerException("delimiters");
        }
        if (delimiters.length == 0) {
            throw new IllegalArgumentException("empty delimiters");
        }
        priorDelimiter = delimiter;
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
        int index = indexOf(buffer, priorDelimiter);
        if(index != 0)
        {
            Object frame = super.decode(ctx, buffer);
            return frame;
        }

        int totalLen = buffer.readableBytes();
        if(totalLen < 62)return null;

        int filePackageLen = (int)(buffer.getUnsignedInt(buffer.readerIndex()+ 58)+ 62);

        if(totalLen < filePackageLen)return null;
        ByteBuf buf = buffer.readBytes(filePackageLen);

        return buf;
    }

    /**
     * Returns the number of bytes between the readerIndex of the haystack and
     * the first needle found in the haystack.  -1 is returned if no needle is
     * found in the haystack.
     */
    private static int indexOf(ByteBuf haystack, ByteBuf needle) {
        for (int i = haystack.readerIndex(); i < haystack.writerIndex(); i ++) {
            int haystackIndex = i;
            int needleIndex;
            for (needleIndex = 0; needleIndex < needle.capacity(); needleIndex ++) {
                if (haystack.getByte(haystackIndex) != needle.getByte(needleIndex)) {
                    break;
                } else {
                    haystackIndex ++;
                    if (haystackIndex == haystack.writerIndex() &&
                            needleIndex != needle.capacity() - 1) {
                        return -1;
                    }
                }
            }

            if (needleIndex == needle.capacity()) {
                // Found the needle from the haystack!
                return i - haystack.readerIndex();
            }
        }
        return -1;
    }



}
